<?php
if (!defined('APP_ID')) { die('No direct script access allowed'); }

class Database_Query_Mysql_Select extends Database_Query_Mysql {
	
	private $_table = array();
	private $_join = array();
	private $_fields = array();
	private $_where = array();
	private $_limit = null;
	private $_offset = null;
	private $_order = array();

	public function table($table, $alias = '') {
		$this->_table[] = array(
			'table' => $table,
			'alias' => $alias
		);
		return $this;
	}

	public function fields($fields) {
		$this->_fields[] = $fields;
		return $this;
	}

	public function where() {
		$args = func_get_args();
		$this->_where[] = $args;
		return $this;
	}

	public function join($table, $alias, $type = Query::JOIN_INNER) {
		$this->_join[] = array(
			'table' => $table,
			'alias' => $alias,
			'type' => $type,
			'expr' => array()
		);
		return $this;
	}

	public function on() {
		$elem = array_pop($this->_join);
		$args = func_get_args();
		$elem['expr'][] = $args;
		array_push($this->_join, $elem);
		return $this;
	}

	public function orderBy($field, $dir = Query::ORDER_ASC) {
		$str = $field;
		if (!empty($dir)) {
			$str .= ' ' . $dir;
		}
		$this->_order[] = $str;
		return $this;
	}

	public function limit($value) {
		$this->_limit = $value;
		return $this;
	}

	public function offset($value) {
		$this->_offset = $value;
		return $this;
	}

	public function compile() {
		$sql = 'SELECT ';
		if (!empty($this->_fields)) {
			$sql .= implode(',', $this->_fields);
		} else {
			$sql .= '*';
		}
		
		$sql .= ' FROM ';
		if (!empty($this->_table)) {
			$tables = array();
			foreach ($this->_table as $table) {
				$table_str = $table['table'];
				if (!empty($table['alias'])) {
					$table_str .= ' AS ' . $table['alias'];
				}
				$tables[] = $table_str;
			}
			$sql .= implode(',', $tables);
		} else {
			throw new Node_Exception('Table must be specified in select query');
		}

		// Join
		if (!empty($this->_join)) {
			foreach ($this->_join as $join) {
				$table_str = $join['table'];
				if (!empty($join['alias'])) {
					$table_str .= ' AS ' . $join['alias'];
				}
				$sql .= ' ' . $join['type'] . ' ' . $table_str;
				
				if (!empty($join['expr'])) {
					$on = $this->parse($join['expr']);
					if (!empty($on)) {
						$sql .= ' ON (' . $on . ')';
					}
				}
			}
		}
		
		// Where
		$where = $this->parse($this->_where);
		if (!empty($where)) {
			$sql .= " WHERE (" . $where . ")";
		}
		
		// Order
		if (!empty($this->_order)) {
			$sql .= " ORDER BY " . implode(',', $this->_order);
		}

		if ($this->_limit !== null) {
			$sql .= " LIMIT " . $this->_limit;
		}
		
		if ($this->_offset !== null) {
			$sql .= " OFFSET " . $this->_offset;
		}

		return $sql;
	}
	
}
